package com.hyt.it.ogt.kq.service.gov.schedule.utils;

import static org.mockito.ArgumentMatchers.contains;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang3.tuple.ImmutablePair;

/**
 * 相似度比较工具类
 */
public class SimilarUtils {

    /**
     * 查找最相似的字符串
     * 
     * @param subject:  字符串，以"|"号隔开
     * @param objects:  查找范围字符串列表， 字符串以“|”隔开
     * @param threshold 相似度阈值, 如果小于该值，则不处理
     * @return
     */
    public static String findSimlarityByOrder(String subject, List<String> objects, int threshold) {
        String bestObject = null;
        int bestDegree = 0;
        for (String item : objects) {
            int degree = simlarityByOrder(subject, item);
            if (degree >= threshold && bestDegree < degree) {
                bestObject = item;
                bestDegree = degree;
            }
        }
        return bestObject;
    }

    /**
     * 查找可以替换的KEY
     * 
     * @param subject:  字符串，以"|"号隔开
     * @param objects:  查找范围字符串列表， 字符串以“|”隔开
     * @param threshold 相似度阈值, 如果小于该值，则不处理
     * @return
     */
    public static ImmutablePair<String, String> findCanReplaceKey(String subject, List<String> objects) {
        String[] subjectSplits = subject.split("\\|");
        int splitLen = subjectSplits.length;

        for (String item : objects) {
            int degree = simlarityByOrder(subject, item);
            if (degree == splitLen) {
                String mergeGroupName = mergeString(item, subject);
                return ImmutablePair.of(item, mergeGroupName);
            }
        }
        return null;
    }

    public static String mergeString(String subject, String object) {
        String[] subjectSplits = subject.split("\\|");
        String[] objectSplits = object.split("\\|");
        for (int index = 0; index < subjectSplits.length; index++) {
            if (subjectSplits[index].equalsIgnoreCase("ANY")) {
                subjectSplits[index] = objectSplits[index];
            }
        }
        return String.join("|", subjectSplits);
    }

    /**
     * 相似度
     * 
     * @param subject
     * @param object
     * @return
     */
    public static int simlarityByOrder(String subject, String object) {
        String[] subjectSplits = subject.split("\\|");
        String[] objectSplits = object.split("\\|");
        int number = 0;
        if (subjectSplits.length == 0 || objectSplits.length == 0) {
            return number;
        }
        for (int i = 0; i < subjectSplits.length; i++) {
            if (objectSplits.length <= i) {
                break;
            }
            if (subjectSplits[i].equalsIgnoreCase("ANY") || objectSplits[i].equalsIgnoreCase("ANY")) {
                number = number + 1;
            } else if (subjectSplits[i].equalsIgnoreCase(objectSplits[i])) {
                number = number + 1;
            } else {
                // 出现不相同，则不再比较
                break;
            }
        }
        return number;
    }

    /**
     * 检测两个字符串数组不否可以合并
     */
    public static boolean canMerge(List<String> subjects, List<String> objects) {
        boolean canMergeFlag = true;
        for (int index = 0; index < subjects.size(); index++) {
            if (subjects.get(index).equals("ANY") || objects.get(index).equals("ANY")) {
                continue;
            }

            if (!subjects.get(index).equalsIgnoreCase(objects.get(index))) {
                canMergeFlag = false;
                break;
            }

        }

        return canMergeFlag;
    }

    /**
     * 检测两个字符串数组是否有交集
     */
    public static boolean intersection(Set<String> subjects, Set<String> objects) {
        if (subjects == null || objects == null) {
            return false;
        }
        for (String subject : subjects) {
            for (String object : objects) {
                if (subject.equalsIgnoreCase(object)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 检测两个字符串数组是否有交集
     */
    public static boolean intersection(String subject, String object, String splitChar) {
        Set<String> subjects = new HashSet<>(Arrays.asList(subject.split(splitChar)));
        Set<String> objects = new HashSet<>(Arrays.asList(object.split(splitChar)));
        return intersection(subjects, objects);
    }

}
